package com.fuyun.microservice.codec;

import com.fuyun.microservice.codec.msg.Header;
import com.fuyun.microservice.codec.msg.Message;
import com.fuyun.microservice.codec.msg.QueryRequestMessage;
import com.fuyun.microservice.utils.BufferUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.coyote.http2.ByteUtil;
import org.springframework.beans.BeanUtils;

import java.util.List;

@Slf4j
@ChannelHandler.Sharable
public class QueryRequestMessageCodec extends MessageToMessageCodec<Message, QueryRequestMessage> {
    private static final int URI_LENGTH = 32;

    @Override
    protected void encode(ChannelHandlerContext ctx, QueryRequestMessage msg, List<Object> out) {
        byte[] reqBytes = msg.getRequestBytes();

        ByteBuf bodyBuffer = Unpooled.buffer(URI_LENGTH + reqBytes.length);
        byte[] uriBytes = BufferUtil.toFixedBytes(msg.getUri(), URI_LENGTH);
        bodyBuffer.writeBytes(uriBytes);
        bodyBuffer.writeBytes(reqBytes);

        msg.setBodyBuffer(bodyBuffer.array());
        ReferenceCountUtil.release(bodyBuffer);

        out.add(msg);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, Message msg, List<Object> out) {
        log.debug("Message -> QueryRequestMessage,source:{}", msg.toString());
        Header header = msg.getHeader();
        short commandId = header.getCommandId();
        if (commandId != PacketType.QUERYREQUEST.getCommandId()) {
            //不解析，交给下一个codec
            out.add(msg);
            return;
        }

        QueryRequestMessage queryRequestMessage = new QueryRequestMessage();
        BeanUtils.copyProperties(msg, queryRequestMessage);
        ByteBuf bodyBuffer = Unpooled.wrappedBuffer(msg.getBodyBuffer());

        String uri = BufferUtil.readStringExcludeEmpty(BufferUtil.toByteArraySafe(bodyBuffer.readBytes(URI_LENGTH)));
        queryRequestMessage.setUri(uri);

        int paramsLength = header.getBodyLength() - (HeaderCodec.HEADER_LENGTH + URI_LENGTH);
        byte[] requesetBytes = BufferUtil.toByteArraySafe(bodyBuffer.readBytes(paramsLength));
//        log.debug("reqbody:{}", new String(requesetBytes, BufferUtil.CHARSET_DEFAULT));
        queryRequestMessage.setRequestBytes(requesetBytes);

        out.add(queryRequestMessage);
    }
}
